//
//    rfnoc-hls-neuralnet: Vivado HLS code for neural-net building blocks
//
//    Copyright (C) 2017 EJ Kreinar
//
//    This program is free software: you can redistribute it and/or modify
//    it under the terms of the GNU General Public License as published by
//    the Free Software Foundation, either version 3 of the License, or
//    (at your option) any later version.
//
//    This program is distributed in the hope that it will be useful,
//    but WITHOUT ANY WARRANTY; without even the implied warranty of
//    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
//    GNU General Public License for more details.
//
//    You should have received a copy of the GNU General Public License
//    along with this program.  If not, see <http://www.gnu.org/licenses/>.
//
#include <fstream>
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <math.h>

#include "firmware/parameters.h"
#include "firmware/myproject.h"
#include "nnet_helpers.h"


int main(int argc, char **argv)
{
    
    input_t  data_str[IN_HEIGHT][IN_WIDTH][N_CHAN] = {0.00392156885937, 0.603921592236, 0.992156863213, 0.352941185236, 0.0, 0.0, 0.0, 0.0, 0.0, 0.54509806633, 0.992156863213, 0.745098054409, 0.00784313771874, 0.0, 0.0, 0.0, 0.0, 0.0431372560561, 0.745098054409, 0.992156863213, 0.274509817362, 0.0, 0.0, 0.0, 0.0, 0.0, 0.137254908681, 0.945098042488, 0.882352948189, 0.627451002598, 0.423529416323, 0.00392156885937, 0.0, 0.0, 0.0, 0.317647069693, 0.941176474094, 0.992156863213, 0.992156863213, 0.466666668653, 0.0, 0.0, 0.0, 0.0, 0.176470592618, 0.729411780834, 0.992156863213, 0.992156863213, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0627451017499, 0.364705890417, 0.988235294819, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.976470589638};

/*
    result_t res_str[OUT_HEIGHT][OUT_WIDTH][N_FILT];
    for(int i=0; i<OUT_HEIGHT; i++){
	for(int j=0; j<OUT_WIDTH; j++){
	    for(int k=0; k<N_FILT; k++){
		res_str[i][j][k]=0;
	    }
	}
    }
*/
    result_t res_str[N_OUTPUTS];
    for(int i=0; i<N_OUTPUTS; i++){
	res_str[i]=0;
    }

    unsigned short size_in, size_out;
    myproject(data_str, res_str, size_in, size_out);


/*
    result_t res_expected[OUT_HEIGHT][OUT_WIDTH][N_FILT] =  {0.0466737786483, 0.190576726396, 0.168259065802, 0.52669304033, 0.775213536079, 0.701346987684, 1.1021222437, 0.472490036685, 0.516853388603, 0.189824754198, 0.00391734644654, 0.00150715600466, 1.45996164065e-05, 0.00025122781517, 1.45996164065e-05, 0.00025122781517, -0.0311477145005, 0.430254304607, -0.186401579325, 1.05066161772, 0.25435489064, 1.28714936395, 1.05908089524, 1.10925977846, 0.93858027106, 0.477270299394, 0.139790173824, 0.0457719432306, 1.45996164065e-05, 0.00025122781517, 1.45996164065e-05, 0.00025122781517, 0.00426168341073, 0.289271617134, -0.164457324689, 0.747978681524, -0.177696008031, 1.3204852881, 0.576644476707, 1.2150626721, 1.3438041771, 0.866074317892, 0.868877109344, 0.241420293052, 0.475155916269, 0.0965736748767, 0.212264817412, 0.0680287720752, 0.000644565123366, 0.022405886848, -0.0112101703708, 0.415800714691, -0.213106009905, 0.882747644384, -0.0918816810299, 1.2379381003, 0.872867163474, 1.28431087156, 1.2381852234, 0.868448490102, 1.11623221284, 0.474721396167, 0.843231972511, 0.239838877518, 1.45996164065e-05, 0.00025122781517, 0.00201903536799, 0.0707433240605, -0.0462704932143, 0.565226429899, -0.318521413748, 0.936228388746, -0.0663303768088, 1.54031055589, 0.573166724498, 1.5757287087, 1.02884512788, 1.20387941023, 1.21578603631, 0.712719971139, 1.45996164065e-05, 0.00025122781517, 1.45996164065e-05, 0.00025122781517, 0.0046534363355, 0.163390079339, -0.0772085225035, 0.550400728185, -0.266109559481, 0.972513789136, -0.206673834269, 1.59389596601, 0.216249343212, 1.62791710516, 0.735305544193, 1.11209695955, 1.45996164065e-05, 0.00025122781517, 1.45996164065e-05, 0.00025122781517, 1.45996164065e-05, 0.00025122781517, 0.0025917312305, 0.0908839272452, -0.036832712387, 0.40454598685, -0.185482147877, 0.76140450855, -0.105173829739, 1.41187124868, 0.170504566486, 0.976512187917, 1.45996164065e-05, 0.00025122781517, 1.45996164065e-05, 0.00025122781517, 1.45996164065e-05, 0.00025122781517, 1.45996164065e-05, 0.00025122781517, 0.000930913112825, 0.0324761884403, -0.00962756367517, 0.193422848184, -0.149595204537, 0.777303987939, -0.417878333275, 0.607939535577};

    
    for(int i=0; i<OUT_HEIGHT; i++){
	for(int j=0; j<OUT_WIDTH; j++){
	    for(int k=0; k<N_FILT; k++){
		std::cout << res_str[i][j][k] << " (expected " << res_expected[i][j][k] << ", " << 100.0*((float)res_str[i][j][k]-(float)res_expected[i][j][k])/(float)res_expected[i][j][k] << " percent difference)" << std::endl;
            }
	}
    }
    //std::cout << std::endl;
    */

    result_t res_expected[N_OUTPUTS] = {0.00864355822657, 0.0363428907592, 0.00937409083393, 0.195389670428, 0.0304245604585, 0.246102922155, 0.133947623317, 0.107121621975, 0.175117479762, 0.057535582084};  
    for(int i=0; i<N_OUTPUTS; i++){
	std::cout << res_str[i] << " (expected " << res_expected[i] << ", " << 100.0*((float)res_str[i]-(float)res_expected[i])/(float)res_expected[i] << " percent difference)" << std::endl;
    }
  
    return 0;
}
